package com.ruoyi.system.service.impl;


import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.domain.dto.H5.PersonalDataDto;
import com.ruoyi.system.domain.dto.H5.PersonalDataResultDto;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.context.annotation.Lazy;
import org.springframework.web.multipart.MultipartFile;

import java.awt.font.TextHitInfo;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.constant.CacheConstants;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.enums.PlayerLogType;
import com.ruoyi.common.core.utils.CommonStreamUtil;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.*;
import com.ruoyi.system.mapper.BaseBasketballTeamMapper;
import com.ruoyi.system.mapper.BasePlayerLogMapper;
import com.ruoyi.system.mapper.BasketballPlayerAndTeamMapper;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.mapper.BaseTournamentMapper;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import static com.ruoyi.common.core.utils.PageUtils.startPage;


/**
 * 赛事Service业务层处理
 *
 * @author wangbj
 * @date 2024-04-16
 */
@Slf4j
@Service
public class BaseTournamentServiceImpl extends ServiceImpl<BaseTournamentMapper, BaseTournament> implements IBaseTournamentService {
    @Resource
    private BaseTournamentMapper baseTournamentMapper;

    @Resource
    BasePlayerLogMapper basePlayerLogMapper;

    @Resource
    @Lazy
    private IBasePlayerLogService basePlayerLogService;

    @Resource
    BaseBasketballTeamMapper baseBasketballTeamMapper;

    @Resource
    RedisService redisService;

    @Resource
    LoginUserSetUtil loginUserSetUtil;

    @Resource
    private IBaseTournamentPersonnelService iBaseTournamentPersonnelService;

    @Resource
    private IBaseBasketballPlayerService iBaseBasketballPlayerService;

    @Resource
    private IBaseCoachService iBaseCoachService;

    @Resource
    private IBaseTeanGroupingPlayTeamService iBaseTeanGroupingPlayTeamService;

    @Resource
    private IBaseContestService iBaseContestService;
    @Resource
    private IBaseLivePlayBackEvenService iBaseLivePlayBackEvenService;
    @Resource
    private BasketballPlayerAndTeamMapper basketballPlayerAndTeamMapper;
    @Resource
    private IBaseTeamGroupingService iBaseTeamGroupingService;
    @Resource
    private RedissonClient redisson;
    @Resource
    private ISysUserService sysUserService;

    public static final String PREFIX = "basketball:team:id:";
    @Value("${OSS.ENDPOINT}")
    private String ENDPOINT;

    @Value("${OSS.ACCESS_KEY_ID}")
    private String ACCESS_KEY_ID;

    @Value("${OSS.ACCESS_KEY_SECRET}")
    private String ACCESS_KEY_SECRET;

    @Value("${OSS.BUCKET_NAME_OPEN}")
    private String bucketName;

    /**
     * 查询赛事
     *
     * @param id 赛事主键
     * @return 赛事
     */
    @Override
    public BaseTournament selectBaseTournamentById(Long id) {
        BaseTournament baseTournament = baseTournamentMapper.selectById(id);
        AssertUtil.notNull(baseTournament, "查询失败");
        BaseBasketballTeam baseBasketballTeam = baseBasketballTeamMapper.selectById(baseTournament.getTeamOneId());
        BaseBasketballTeam baseBasketballTeam1 = baseBasketballTeamMapper.selectById(baseTournament.getTeamTwoId());
        List<BasePlayerLog> playerLogList = basePlayerLogMapper.selectList(Wrappers.<BasePlayerLog>lambdaQuery()
                .eq(BasePlayerLog::getTournamentId, id)
                .eq(BasePlayerLog::getIsDeleted, 0)
        );
        Map<Long, List<BasePlayerLog>> collect = playerLogList.stream().collect(Collectors.groupingBy(BasePlayerLog::getBasketballTeamId));
        if (Objects.nonNull(baseBasketballTeam)) {
            baseTournament.setTeamOneName(baseBasketballTeam.getTeamName());
            baseTournament.setTeamOneLogo(baseBasketballTeam.getTeamLogo());
        }
        if (Objects.nonNull(baseBasketballTeam1)) {
            baseTournament.setTeamTwoName(baseBasketballTeam1.getTeamName());
            baseTournament.setTeamTwoLogo(baseBasketballTeam1.getTeamLogo());
        }
        Long subsection;
        if (baseTournament.getSubsection() >= 4) {
            subsection = 4L;
        } else {
            subsection = baseTournament.getSubsection();
        }
        if (collect.containsKey(baseTournament.getTeamOneId())) {
            List<BasePlayerLog> playerLogList1 = collect.get(baseTournament.getTeamOneId());
            Long reduce = playerLogList1.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum);
            baseTournament.setTeamOneScore(reduce);
            List<BasePlayerLog> playerLogList3 = CommonStreamUtil.filter(playerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()));

            int size = CommonStreamUtil.filter(playerLogList3, o -> subsection.equals(o.getSubsection())).size();
            if (subsection == 4L) {
                size = size + CommonStreamUtil.filter(playerLogList3, o -> subsection < o.getSubsection()).size();
            }
            baseTournament.setOneFoul(size);
        }
        if (collect.containsKey(baseTournament.getTeamTwoId())) {
            List<BasePlayerLog> playerLogList1 = collect.get(baseTournament.getTeamTwoId());
            Long reduce = playerLogList1.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum);
            baseTournament.setTeamTwoScore(reduce);
            List<BasePlayerLog> playerLogList3 = CommonStreamUtil.filter(playerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()));
            int size = CommonStreamUtil.filter(playerLogList3, o -> subsection.equals(o.getSubsection())).size();
            if (subsection == 4L) {
                size = size + CommonStreamUtil.filter(playerLogList3, o -> subsection < o.getSubsection()).size();
            }
            baseTournament.setTwoFoul(size);
        }
        Object cacheObject = redisService.getCacheObject(Constants.LIVE_NUM + id);
        long num = cacheObject == null ? 0 : Long.valueOf((Integer) cacheObject);
        if (baseTournament.getLiveNum() > num) {
            num = baseTournament.getLiveNum() + num;
            redisService.setCacheObject(Constants.LIVE_NUM + id, num);
        }
        baseTournament.setLiveNum(num);

        List<BaseTeamGrouping> baseTeamGroupings = iBaseTeamGroupingService.teamRankingList(baseTournament.getContestId());
        if (CollUtil.isNotEmpty(baseTeamGroupings)) {
            for (BaseTeamGrouping item : baseTeamGroupings) {
                List<BaseTeanGroupingPlayTeam> teanGroupingPlayTeamList = item.getTeanGroupingPlayTeamList();
                if (CollUtil.isNotEmpty(teanGroupingPlayTeamList)) {
                    int teamNum = 1;
                    for (BaseTeanGroupingPlayTeam team : teanGroupingPlayTeamList) {
                        if (Objects.equals(team.getBasketballTeamId(), baseTournament.getTeamOneId())) {
                            baseTournament.setTeamOneRanking(item.getName() + "第" + teamNum);
                        }
                        if (Objects.equals(team.getBasketballTeamId(), baseTournament.getTeamTwoId())) {
                            baseTournament.setTeamTwoRanking(item.getName() + "第" + teamNum);
                        }
                        teamNum++;
                    }
                }
            }
        }
        return baseTournament;
    }

    /**
     * 获取比赛详情包含球队球员 / 工作人员
     *
     * @param id
     * @return
     */
    @Override
    public BaseTournamentResponseVO selectById(Long id) {
        BaseTournament item = selectBaseTournamentById(id);
        if (ObjectUtil.isNull(item)) {
            return null;
        }
        BaseTournamentResponseVO baseTournamentResponseVO = BeanUtil.copyProperties(item, BaseTournamentResponseVO.class);
        //拿到队伍信息
        setTeam(baseTournamentResponseVO, item.getTeamOneId(), PREFIX.concat(String.valueOf(item.getTeamOneId())), 1);
        setTeam(baseTournamentResponseVO, item.getTeamTwoId(), PREFIX.concat(String.valueOf(item.getTeamTwoId())), 2);

        //球队球员信息
        setPlayer(baseTournamentResponseVO);
        //球队教练组成员
        setCoach(baseTournamentResponseVO);

        //工作人员信息
        setTournamentPersonnel(baseTournamentResponseVO, item.getId());

        return baseTournamentResponseVO;
    }

    @Override
    public Map<String, Object> getTeamStatsCaption(Long scheduleId) {
        Map<String, Object> map = new HashMap<>();

        BaseTournament item = getById(scheduleId);
        if (ObjectUtil.isNull(item)) {
            return map;
        }
        BaseBasketballTeam baseBasketballTeamOne = baseBasketballTeamMapper.selectById(item.getTeamOneId());
        BaseBasketballTeam baseBasketballTeamTwo = baseBasketballTeamMapper.selectById(item.getTeamOneId());

        List<Map<String, Object>> listMap = new ArrayList<>();
        Map<String, Object> mapMall = new HashMap<>();
        mapMall.put("value0", "球队名称");
        mapMall.put("value1", baseBasketballTeamOne.getTeamName());
        mapMall.put("value2", baseBasketballTeamTwo.getTeamName());
        listMap.add(mapMall);
        List<BasePlayerLog> basePlayerLogs = basePlayerLogMapper.selectList(Wrappers.<BasePlayerLog>lambdaQuery()
                .in(BasePlayerLog::getBasketballTeamId, baseBasketballTeamOne.getId(), baseBasketballTeamTwo.getId())
                .eq(BasePlayerLog::getTournamentId, scheduleId));
        Map<Long, List<BasePlayerLog>> collect = basePlayerLogs.stream().collect(Collectors.groupingBy(BasePlayerLog::getBasketballTeamId));
        List<BasePlayerLog> basePlayerLogsOne = collect.get(baseBasketballTeamOne.getId());
        List<BasePlayerLog> basePlayerLogsTwo = collect.get(baseBasketballTeamTwo.getId());
        basePlayerLogsOne = CollUtil.isNotEmpty(basePlayerLogsOne) ? basePlayerLogsOne : new ArrayList<>();
        basePlayerLogsTwo = CollUtil.isNotEmpty(basePlayerLogsTwo) ? basePlayerLogsTwo : new ArrayList<>();

        Map<String, Object> mapMall1 = new HashMap<>();
        mapMall1.put("value0", "比分");
        mapMall1.put("value1", basePlayerLogsOne.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        mapMall1.put("value2", basePlayerLogsTwo.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        listMap.add(mapMall1);

        Map<String, Object> mapMall2 = new HashMap<>();
        mapMall2.put("value0", "篮板");
        mapMall2.put("value1", basePlayerLogsOne.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.BACKBOARD.getCode())).count());
        mapMall2.put("value2", basePlayerLogsTwo.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.BACKBOARD.getCode())).count());
        listMap.add(mapMall2);

        Map<String, Object> mapMall3 = new HashMap<>();
        mapMall3.put("value0", "助攻");
        mapMall3.put("value1", basePlayerLogsOne.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.ASSIST.getCode())).count());
        mapMall3.put("value2", basePlayerLogsTwo.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.ASSIST.getCode())).count());
        listMap.add(mapMall3);

        Map<String, Object> mapMall4 = new HashMap<>();
        mapMall4.put("value0", "盖帽");
        mapMall4.put("value1", basePlayerLogsOne.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.BLOCK_SHOT.getCode())).count());
        mapMall4.put("value2", basePlayerLogsTwo.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.BLOCK_SHOT.getCode())).count());
        listMap.add(mapMall4);

        Map<String, Object> mapMall5 = new HashMap<>();
        mapMall5.put("value0", "犯规");
        mapMall5.put("value1", basePlayerLogsOne.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.FOUL.getCode())).count());
        mapMall5.put("value2", basePlayerLogsTwo.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.FOUL.getCode())).count());
        listMap.add(mapMall5);

        Map<String, Object> mapMall6 = new HashMap<>();
        mapMall6.put("value0", "两分球");
        mapMall6.put("value1", basePlayerLogsOne.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.TWO_POINT_HIT.getCode())).count());
        mapMall6.put("value2", basePlayerLogsTwo.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.TWO_POINT_HIT.getCode())).count());
        listMap.add(mapMall6);

        Map<String, Object> mapMall7 = new HashMap<>();
        mapMall7.put("value0", "三分球");
        mapMall7.put("value1", basePlayerLogsOne.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.THREE_POINT_HIT.getCode())).count());
        mapMall7.put("value2", basePlayerLogsTwo.stream().filter(vo -> Objects.equals(vo.getType(), PlayerLogType.THREE_POINT_HIT.getCode())).count());
        listMap.add(mapMall7);

        map.put("data", listMap);
        return map;
    }

    @Override
    public LinkedHashMap<String, Object> getTournamentData(Long tournamentId, Long teamId) {
        BaseTournament baseTournament = getById(tournamentId);
        if (Objects.isNull(baseTournament)) {
            throw new RuntimeException("比赛不存在!");
        }
        BaseBasketballTeam baseBasketballTeam = baseBasketballTeamMapper.selectById(teamId);

//        Long teamOneId = baseTournament.getTeamOneId();
//        Long teamTwoId = baseTournament.getTeamTwoId();
//        List<Long> teamIds = new ArrayList<>();
//        teamIds.add(teamOneId);
//        teamIds.add(teamTwoId);

        List<BasePlayerLog> playerLogList = basePlayerLogMapper.selectList(Wrappers.<BasePlayerLog>lambdaQuery()
                .eq(BasePlayerLog::getTournamentId, tournamentId)
                .eq(BasePlayerLog::getBasketballTeamId, teamId)
                .eq(BasePlayerLog::getIsDeleted, 0));

        List<Map<String, Object>> teamOneData = new ArrayList<>();
        List<Map<String, Object>> teamTwoData = new ArrayList<>();
//        for (Long teamId:teamIds) {
        List<BasketballPlayerAndTeam> basketballPlayerAndTeams = basketballPlayerAndTeamMapper.selectByTeamThenPlay(teamId);
        if (CollUtil.isEmpty(basketballPlayerAndTeams)) {
            throw new RuntimeException("比赛球队出错!");
        }
        //获取球员
        Set<Long> playerIds = CommonStreamUtil.transSet(basketballPlayerAndTeams, BasketballPlayerAndTeam::getPlayerId);
        List<BaseBasketballPlayer> baseBasketballPlayers = iBaseBasketballPlayerService.listByIds(playerIds);
        if (CollUtil.isEmpty(baseBasketballPlayers)) {
            throw new RuntimeException("比赛球员出错!");
        }
        playerLogList = CommonStreamUtil.filter(playerLogList, o -> Objects.nonNull(o.getBasketballPlayerId()));
        Map<Long, List<BasePlayerLog>> playerMap = CommonStreamUtil.group(playerLogList, BasePlayerLog::getBasketballPlayerId);
        baseBasketballPlayers.forEach(play -> {
            Map<String, Object> map = new HashMap<>();

            List<Map<String, Object>> mapList = new ArrayList<>();

            //当前球员的得分操作
            List<BasePlayerLog> playerLog = new ArrayList<>();
            List<BasePlayerLog> playerLogList1 = playerMap.get(play.getId());
            playerLog = Objects.isNull(playerLogList1) ? playerLog : playerLogList1;
            //总分
            Long reduce = playerLog.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum);

            Map<String, Object> data = new HashMap<>();
            data.put("typeStr", "得分");
            data.put("typeCount", reduce);
            mapList.add(data);

            int backboard = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.BACKBOARD.getCode())).size();
            Map<String, Object> data1 = new HashMap<>();
            data1.put("typeStr", "篮板");
            data1.put("typeCount", backboard);
            mapList.add(data1);

            int assist = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.ASSIST.getCode())).size();
            Map<String, Object> data2 = new HashMap<>();
            data2.put("typeStr", "助攻");
            data2.put("typeCount", assist);
            mapList.add(data2);
            //三分命中
            int threePointHit = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.THREE_POINT_HIT.getCode())).size();
            //三分不中
            int threeNotPointHit = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.THREE_NOT_POINT_HIT.getCode())).size();
            int twoPointHit = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.TWO_POINT_HIT.getCode())).size();
            int twoNotPointHit = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.TWO_NOT_POINT_HIT.getCode())).size();
            int pointHit = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.POINT_HIT.getCode())).size();
            int notPointHit = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.NOT_POINT_HIT.getCode())).size();


            Map<String, Object> data3 = new HashMap<>();
            data3.put("typeStr", "投篮");
            data3.put("typeCount", threePointHit + threeNotPointHit + twoPointHit + twoNotPointHit);
            mapList.add(data3);

            Map<String, Object> data4 = new HashMap<>();
            data4.put("typeStr", "三分命中");
            data4.put("typeCount", threePointHit);
            mapList.add(data4);

            int threeAllPointHit = threePointHit + threeNotPointHit;
            BigDecimal divide = BigDecimal.ZERO;
            if (threePointHit > 0) {
                divide = BigDecimal.valueOf(threePointHit).divide(BigDecimal.valueOf(threeAllPointHit), 2, RoundingMode.HALF_UP);
            }
            Map<String, Object> data5 = new HashMap<>();
            data5.put("typeStr", "三分命中率");
            data5.put("typeCount", divide.toPlainString() + "%");
            mapList.add(data5);

            Map<String, Object> data6 = new HashMap<>();
            data6.put("typeStr", "罚球命中");
            data6.put("typeCount", pointHit);
            mapList.add(data6);

            int allPointHit = pointHit + notPointHit;
            BigDecimal dividePointHit = BigDecimal.ZERO;
            if (pointHit > 0) {
                dividePointHit = BigDecimal.valueOf(pointHit).divide(BigDecimal.valueOf(allPointHit), 2, RoundingMode.HALF_UP);
            }
            Map<String, Object> data7 = new HashMap<>();
            data7.put("typeStr", "罚球命中率");
            data7.put("typeCount", dividePointHit.toPlainString() + "%");
            mapList.add(data7);

            int stral = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.STRAL.getCode())).size();
            Map<String, Object> data8 = new HashMap<>();
            data8.put("typeStr", "抢断");
            data8.put("typeCount", stral);
            mapList.add(data8);

            int mistake = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.MISTAKE.getCode())).size();
            Map<String, Object> data9 = new HashMap<>();
            data9.put("typeStr", "失误");
            data9.put("typeCount", mistake);
            mapList.add(data9);

            int blockShot = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.BLOCK_SHOT.getCode())).size();
            Map<String, Object> data10 = new HashMap<>();
            data10.put("typeStr", "盖帽");
            data10.put("typeCount", blockShot);
            mapList.add(data10);

            int foul = CommonStreamUtil.filter(playerLog, o -> Objects.equals(o.getType(), PlayerLogType.FOUL.getCode())).size();
            Map<String, Object> data11 = new HashMap<>();
            data11.put("typeStr", "犯规");
            data11.put("typeCount", foul);
            mapList.add(data11);

            map.put("playerName", play.getName());
            map.put("playerNumber", play.getPlayerNumber());
            map.put("playData", mapList);

            teamOneData.add(map);
        });

//        }
        LinkedHashMap<String, Object> resultMap = new LinkedHashMap<>();
        resultMap.put("teamId", baseBasketballTeam.getId());
        resultMap.put("teamName", baseBasketballTeam.getTeamName());
        resultMap.put("teamData", teamOneData);
//
//        resultMap.put("teamTwoId",baseTournament.getTeamTwoId());
//        resultMap.put("teamTwoName",baseTournament.getTeamTwoName());
//        resultMap.put("teamTwoData",teamTwoData);

        return resultMap;
    }

    @Override
    public BaseContest getContestLogo(Long tournamentId) {
        BaseTournament byId = this.getById(tournamentId);
        if (Objects.isNull(byId)) {
            throw new RuntimeException("比赛id错误");
        }
        return iBaseContestService.getById(byId.getContestId());
    }

    @Override
    public List<BaseTournament> selectByIdsAndState(List<Long> tournamentIds, int state, Date now) {
        return this.list(Wrappers.<BaseTournament>lambdaQuery()
                .eq(BaseTournament::getState, state)
                .in(BaseTournament::getId, tournamentIds)
                .le(BaseTournament::getTournamentEndTime, now)
        );
    }

    @Override
    public PlayTeamDataVO teamData(Long teamId) {
        PlayTeamDataVO playTeamDataVO = new PlayTeamDataVO();

        BaseBasketballTeam baseBasketballTeam = baseBasketballTeamMapper.selectById(teamId);
        if (Objects.isNull(baseBasketballTeam)) {
            throw new RuntimeException("比赛球队出错!");
        }
        List<BaseTournament> tournamentList = baseMapper.selectBaseTournamentListTeam(baseBasketballTeam.getLeagueId(), 2, teamId);
        if (CollUtil.isEmpty(tournamentList)) {
            return playTeamDataVO;
        }
        //能力 柱状图
        BaseTeamCompareVO teamCompare = basePlayerLogMapper.getTeamCompare(teamId, null);
        playTeamDataVO.setTeamCompare(teamCompare);

        BaseTournament existFirst = CommonStreamUtil.isExistFirst(tournamentList);
        BaseContest byId = iBaseContestService.getById(existFirst.getContestId());
        playTeamDataVO.setScoringWay(byId.getScoringWay());


        int size = tournamentList.size();
        CopyBaseTeamCompareVO copyTeamCompare = new CopyBaseTeamCompareVO();
        copyTeamCompare.setEf(BigDecimal.valueOf(teamCompare.getEf()).divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP));
        copyTeamCompare.setQd(BigDecimal.valueOf(teamCompare.getQd()).divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP));
        copyTeamCompare.setLb(BigDecimal.valueOf(teamCompare.getLb()).divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP));
        copyTeamCompare.setGm(BigDecimal.valueOf(teamCompare.getGm()).divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP));
        copyTeamCompare.setFq(BigDecimal.valueOf(teamCompare.getFq()).divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP));
        copyTeamCompare.setSf(BigDecimal.valueOf(teamCompare.getSf()).divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP));
        copyTeamCompare.setZg(BigDecimal.valueOf(teamCompare.getZg()).divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP));
        copyTeamCompare.setFg(BigDecimal.valueOf(teamCompare.getFg()).divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP));
        copyTeamCompare.setScore(BigDecimal.valueOf(teamCompare.getScore()).divide(BigDecimal.valueOf(size), 2, RoundingMode.HALF_UP));

        playTeamDataVO.setCopyTeamCompare(copyTeamCompare);

        List<BaseTournament> win = CommonStreamUtil.filter(tournamentList, o -> Objects.equals(o.getIsWin(), teamId));
        List<BaseTournament> lose = CommonStreamUtil.filter(tournamentList, o -> !Objects.equals(o.getIsWin(), teamId));
        playTeamDataVO.setWinNum(win.size());
        playTeamDataVO.setLoseNum(lose.size());
        playTeamDataVO.setNum("排名NO.1");

        List<BaseTeamGrouping> baseTeamGroupings = iBaseTeamGroupingService.teamRankingList(existFirst.getContestId());
        if (CollUtil.isNotEmpty(baseTeamGroupings)) {
            for (BaseTeamGrouping item : baseTeamGroupings) {
                List<BaseTeanGroupingPlayTeam> teanGroupingPlayTeamList = item.getTeanGroupingPlayTeamList();
                if (CollUtil.isNotEmpty(teanGroupingPlayTeamList)) {
                    int num = 1;
                    for (BaseTeanGroupingPlayTeam team : teanGroupingPlayTeamList) {
                        if (Objects.equals(team.getBasketballTeamId(), teamId)) {
                            playTeamDataVO.setNum(item.getName() + " 排名NO." + num);
                        }
                        num++;
                    }
                }
            }
        }
        return playTeamDataVO;
    }

    @Override
    public List<Map<String, Object>> playTeamData(Long teamId) {
        BaseBasketballTeam baseBasketballTeam = baseBasketballTeamMapper.selectById(teamId);
        if (Objects.isNull(baseBasketballTeam)) {
            throw new RuntimeException("比赛球队出错!");
        }
        List<BasketballPlayerAndTeam> basketballPlayerAndTeams = basketballPlayerAndTeamMapper.selectByTeamThenPlay(teamId);
        if (CollUtil.isEmpty(basketballPlayerAndTeams)) {
            throw new RuntimeException("比赛球队出错!");
        }
        //获取球员
        Set<Long> playerIds = CommonStreamUtil.transSet(basketballPlayerAndTeams, BasketballPlayerAndTeam::getPlayerId);
        List<BaseBasketballPlayer> baseBasketballPlayers = iBaseBasketballPlayerService.listByIds(playerIds);
        if (CollUtil.isEmpty(baseBasketballPlayers)) {
            throw new RuntimeException("比赛球员出错!");
        }
        Set<Long> longs = CommonStreamUtil.transSet(baseBasketballPlayers, BaseBasketballPlayer::getId);
        List<BasePlayerLog> list = basePlayerLogMapper.selectList(Wrappers.<BasePlayerLog>lambdaQuery()
                .eq(BasePlayerLog::getBasketballTeamId, teamId)
                .in(BasePlayerLog::getBasketballPlayerId, longs)
                .ne(BasePlayerLog::getType, PlayerLogType.OVER.getCode())
                .eq(BasePlayerLog::getIsDeleted, 0));

        //获取当前球队总比赛次数
        List<BaseTournament> tournamentList = baseMapper.selectBaseTournamentListTeam(baseBasketballTeam.getLeagueId(), 2, teamId);
        //获取联赛
        BaseContest contest = iBaseContestService.getById(baseBasketballTeam.getLeagueId());


        List<Map<String, Object>> playMapList = new ArrayList<>();

        for (BaseBasketballPlayer key : baseBasketballPlayers) {
            Map<String, Object> playMap = new HashMap<>();

            List<BasePlayerLog> filter = CommonStreamUtil.filter(list, vo -> Objects.equals(vo.getBasketballPlayerId(), key.getId()));

            List<Map<String, Object>> typeMapList = new ArrayList<>();
            for (PlayerLogType keyLog : PlayerLogType.values()) {
                if (keyLog.getCode().equals(PlayerLogType.STOP.getCode())) {
                    continue;
                }
                if (keyLog.getCode().equals(PlayerLogType.OVER.getCode())) {
                    continue;
                }
                Map<Long, List<BasePlayerLog>> typeList = CommonStreamUtil.group(filter, BasePlayerLog::getType);

                if (Objects.nonNull(contest) && Objects.equals(contest.getScoringWay(), 1L)) {
                    if (Objects.equals(keyLog.getCode(), PlayerLogType.THREE_POINT_HIT.getCode())) {
                        continue;
                    }
                    if (Objects.equals(keyLog.getCode(), PlayerLogType.THREE_NOT_POINT_HIT.getCode())) {
                        continue;
                    }
                } else {
                    if (Objects.equals(keyLog.getCode(), PlayerLogType.ONE_POINT_HIT.getCode())) {
                        continue;
                    }
                    if (Objects.equals(keyLog.getCode(), PlayerLogType.ONE_NOT_POINT_HIT.getCode())) {
                        continue;
                    }
                }

                List<BasePlayerLog> basePlayerLogs = typeList.get(keyLog.getCode());
                Map<String, Object> map = new HashMap<>();
                //类型名称
                map.put("typeStr", PlayerLogType.getValue(keyLog.getCode()));
                map.put("typeCount", 0);
                map.put("type", keyLog.getCode());
                if (CollUtil.isNotEmpty(basePlayerLogs)) {
                    //类型次数
                    map.put("typeCount", basePlayerLogs.size());
                }
                typeMapList.add(map);

            }
            Long reduce = filter.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum);

            //罚球
            long notPointHit = BasePlayerLogServiceImpl.buildTypeName(filter, PlayerLogType.POINT_HIT.getCode(), PlayerLogType.NOT_POINT_HIT.getCode(), "罚球总命中率", 90, typeMapList);
            long twoNotPointHit = BasePlayerLogServiceImpl.buildTypeName(filter, PlayerLogType.TWO_POINT_HIT.getCode(), PlayerLogType.TWO_NOT_POINT_HIT.getCode(), "二分总命中率", 92, typeMapList);
            //如果是3v3
            long threeNotPointHit;
            long threePointHit;
            if (Objects.nonNull(contest) && Objects.equals(contest.getScoringWay(), 1L)) {
                threeNotPointHit = BasePlayerLogServiceImpl.buildTypeName(filter, PlayerLogType.ONE_POINT_HIT.getCode(), PlayerLogType.ONE_NOT_POINT_HIT.getCode(), "一分总命中率", 91, typeMapList);
                threePointHit = CommonStreamUtil.filter(filter, o -> Objects.equals(o.getType(), PlayerLogType.ONE_POINT_HIT.getCode())).size();
            } else {
                threeNotPointHit = BasePlayerLogServiceImpl.buildTypeName(filter, PlayerLogType.THREE_POINT_HIT.getCode(), PlayerLogType.THREE_NOT_POINT_HIT.getCode(), "三分总命中率", 93, typeMapList);
                threePointHit = CommonStreamUtil.filter(filter, o -> Objects.equals(o.getType(), PlayerLogType.THREE_POINT_HIT.getCode())).size();
            }
            //球员效率值
            //篮板
            int backboard = CommonStreamUtil.filter(filter, o -> Objects.equals(o.getType(), PlayerLogType.BACKBOARD.getCode())).size();
            int assist = CommonStreamUtil.filter(filter, o -> Objects.equals(o.getType(), PlayerLogType.ASSIST.getCode())).size();
            int stral = CommonStreamUtil.filter(filter, o -> Objects.equals(o.getType(), PlayerLogType.STRAL.getCode())).size();
            int blockShot = CommonStreamUtil.filter(filter, o -> Objects.equals(o.getType(), PlayerLogType.BLOCK_SHOT.getCode())).size();
            //失误
            int mistake = CommonStreamUtil.filter(filter, o -> Objects.equals(o.getType(), PlayerLogType.MISTAKE.getCode())).size();

            // 总分+篮板+助攻+抢断+盖帽 - （二分不中+三分不中+罚球不中+失误）
            long per = (reduce + backboard + assist + stral + blockShot) - (twoNotPointHit + threeNotPointHit + notPointHit + mistake);
            Map<String, Object> pointHitMap = new HashMap<>();
            //罚球
            int i = tournamentList.size();
            BigDecimal divide = BigDecimal.ZERO;
            if (per > 0 && i > 0) {
                divide = BigDecimal.valueOf(per).divide(BigDecimal.valueOf(i), 2, RoundingMode.HALF_UP);
            }
            pointHitMap.put("typeStr", "效率值");
            pointHitMap.put("typeCount", divide);
            pointHitMap.put("type", 94);
            typeMapList.add(pointHitMap);

            //真实命中率
            //总分 / (2* (二分出手+三分出手+ (0.44*罚球出手) ))
            //二分命中
            long twoPointHit = CommonStreamUtil.filter(filter, o -> Objects.equals(o.getType(), PlayerLogType.TWO_POINT_HIT.getCode())).size();

            //罚球命中
            long pointHit = CommonStreamUtil.filter(filter, o -> Objects.equals(o.getType(), PlayerLogType.POINT_HIT.getCode())).size();
            //二分三分总出手
            long l = twoPointHit + twoNotPointHit + threeNotPointHit + threePointHit;
            //罚球总出手
            double v = 0.44 * (pointHit + notPointHit);
            double v1 = 2 * (l + v);
            Map<String, Object> map = new HashMap<>();
            BigDecimal divide1 = BigDecimal.ZERO;
            if (reduce > 0 && v1 > 0) {
                divide1 = BigDecimal.valueOf(reduce).divide(BigDecimal.valueOf(v1), 2, RoundingMode.HALF_UP);
            }
            map.put("typeStr", "真实命中率");
            map.put("typeCount", divide1);
            map.put("type", 95);
            typeMapList.add(map);

            playMap.put("typeMapList", typeMapList);

            playMap.put("typeScoreSum", reduce);

            playMap.put("name", key.getName());
            playMap.put("code", key.getPlayerNumber());
            playMap.put("img", key.getProfilePicture());
            playMap.put("basketballPlayerId", key.getId());
            playMapList.add(playMap);
        }
        playMapList = CommonStreamUtil.sorted(playMapList, Comparator.comparing(o -> Integer.parseInt(o.get("typeScoreSum").toString())));

        return playMapList;
    }

    @Override
    public BasePdfDataVO getPdfData(Long tournamentId) {
        BasePdfDataVO pdfDataVO = new BasePdfDataVO();
        BaseTournament tournament = this.getById(tournamentId);
        AssertUtil.notNull(tournament, "比赛不存在!");
        pdfDataVO.setAddress(tournament.getAddress());
        pdfDataVO.setTournamentBeginTime(tournament.getTournamentBeginTime());
        List<BasePlayerLog> basePlayerLogList = basePlayerLogMapper.selectByTournamentId(tournamentId);
        //主队
        List<BasePlayerLog> homePlayerLogList = CommonStreamUtil.filter(basePlayerLogList, o -> Objects.equals(o.getBasketballTeamId(), tournament.getTeamOneId()));
        pdfDataVO.setHomeScore(homePlayerLogList.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setHomeOneScore(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 1L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setHomeTwoScore(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 2L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setHomeThreeScore(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 3L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setHomeFourScore(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 4L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setHomeFiveScore(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 5L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setHomeSixScore(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 6L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setHomeSevenScore(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 7L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));

        pdfDataVO.setHomeTeamOneFoul(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 1L) && (Objects.equals(o.getType(), PlayerLogType.TEAM_FOUL.getCode()) || Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()))).count());
        pdfDataVO.setHomeTeamTwoFoul(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 2L) && (Objects.equals(o.getType(), PlayerLogType.TEAM_FOUL.getCode()) || Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()))).count());
        pdfDataVO.setHomeTeamThreeFoul(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 3L) && (Objects.equals(o.getType(), PlayerLogType.TEAM_FOUL.getCode()) || Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()))).count());
        pdfDataVO.setHomeTeamFourFoul(homePlayerLogList.stream().filter(o -> o.getSubsection() >= 4L && (Objects.equals(o.getType(), PlayerLogType.TEAM_FOUL.getCode()) || Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()))).count());
        pdfDataVO.setHomeTeamOneStop(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 1L) && Objects.equals(o.getType(), PlayerLogType.STOP.getCode())).count());
        pdfDataVO.setHomeTeamTwoStop(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 2L) && Objects.equals(o.getType(), PlayerLogType.STOP.getCode())).count());
        pdfDataVO.setHomeTeamThreeStop(homePlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 3L) && Objects.equals(o.getType(), PlayerLogType.STOP.getCode())).count());
        pdfDataVO.setHomeTeamFourStop(homePlayerLogList.stream().filter(o -> o.getSubsection() >= 4L && Objects.equals(o.getType(), PlayerLogType.STOP.getCode())).count());

        List<BasePdfDataPlayListVO> home = buildPdfHomePlayerList(homePlayerLogList, tournament.getTeamOneId());
        pdfDataVO.setPdfHomePlayerList(home);
        BaseBasketballTeam baseBasketballTeam = baseBasketballTeamMapper.selectById(tournament.getTeamOneId());
        if (Objects.nonNull(baseBasketballTeam)) {
            pdfDataVO.setHomeTeamName(baseBasketballTeam.getTeamName());
        }

        //客队
        List<BasePlayerLog> awayPlayerLogList = CommonStreamUtil.filter(basePlayerLogList, o -> Objects.equals(o.getBasketballTeamId(), tournament.getTeamTwoId()));
        pdfDataVO.setAwayScore(awayPlayerLogList.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setAwayOneScore(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 1L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setAwayTwoScore(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 2L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setAwayThreeScore(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 3L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setAwayFourScore(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 4L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setAwayFiveScore(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 5L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setAwaySixScore(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 6L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        pdfDataVO.setAwaySevenScore(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 7L)).map(BasePlayerLog::getScore).reduce(0L, Long::sum));

        pdfDataVO.setAwayTeamOneFoul(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 1L) && (Objects.equals(o.getType(), PlayerLogType.TEAM_FOUL.getCode()) || Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()))).count());
        pdfDataVO.setAwayTeamTwoFoul(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 2L) && (Objects.equals(o.getType(), PlayerLogType.TEAM_FOUL.getCode()) || Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()))).count());
        pdfDataVO.setAwayTeamThreeFoul(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 3L) && (Objects.equals(o.getType(), PlayerLogType.TEAM_FOUL.getCode()) || Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()))).count());
        pdfDataVO.setAwayTeamFourFoul(awayPlayerLogList.stream().filter(o -> o.getSubsection() >= 4L && (Objects.equals(o.getType(), PlayerLogType.TEAM_FOUL.getCode()) || Objects.equals(o.getType(), PlayerLogType.FOUL.getCode()))).count());
        pdfDataVO.setAwayTeamOneStop(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 1L) && Objects.equals(o.getType(), PlayerLogType.STOP.getCode())).count());
        pdfDataVO.setAwayTeamTwoStop(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 2L) && Objects.equals(o.getType(), PlayerLogType.STOP.getCode())).count());
        pdfDataVO.setAwayTeamThreeStop(awayPlayerLogList.stream().filter(o -> Objects.equals(o.getSubsection(), 3L) && Objects.equals(o.getType(), PlayerLogType.STOP.getCode())).count());
        pdfDataVO.setAwayTeamFourStop(awayPlayerLogList.stream().filter(o -> o.getSubsection() >= 4L && Objects.equals(o.getType(), PlayerLogType.STOP.getCode())).count());
        List<BasePdfDataPlayListVO> away = buildPdfHomePlayerList(awayPlayerLogList, tournament.getTeamTwoId());
        pdfDataVO.setPdfAwayPlayerList(away);
        BaseBasketballTeam baseBasketballTeam1 = baseBasketballTeamMapper.selectById(tournament.getTeamTwoId());
        if (Objects.nonNull(baseBasketballTeam1)) {
            pdfDataVO.setAwayTeamName(baseBasketballTeam1.getTeamName());
        }
        return pdfDataVO;
    }

    @Override
    public String downloadPdf(MultipartFile file, String filename) {
        try {
            return ImageToPdf(file, filename);
        } catch (Exception e) {
            e.printStackTrace();
            return "下载pdf失败:" + e.getMessage();
        }
    }

    /**
     * 查询比赛及球队名称
     *
     * @param tournamentId
     * @return
     */
    @Override
    public BaseTournament selectBaseTournamentAndTeamNameById(Long tournamentId) {
        BaseTournament baseTournament = baseTournamentMapper.selectById(tournamentId);
        AssertUtil.notNull(baseTournament, "查询失败");
        BaseBasketballTeam baseBasketballTeam = baseBasketballTeamMapper.selectById(baseTournament.getTeamOneId());
        BaseBasketballTeam baseBasketballTeam1 = baseBasketballTeamMapper.selectById(baseTournament.getTeamTwoId());
        if (Objects.nonNull(baseBasketballTeam)) {
            baseTournament.setTeamOneName(baseBasketballTeam.getTeamName());
            baseTournament.setTeamOneLogo(baseBasketballTeam.getTeamLogo());
        }
        if (Objects.nonNull(baseBasketballTeam1)) {
            baseTournament.setTeamTwoName(baseBasketballTeam1.getTeamName());
            baseTournament.setTeamTwoLogo(baseBasketballTeam1.getTeamLogo());
        }
        return baseTournament;
    }

    @Override
    public PersonalDataResultDto personalData(PersonalDataDto dto) {
        PersonalDataResultDto result = new PersonalDataResultDto();

        //比赛
        BaseTournament baseTournament = selectBaseTournamentAndTeamNameById(dto.getTournamentId());
        result.setTeamOneName(baseTournament.getTeamOneName());
        result.setTeamOneScore(baseTournament.getTeamOneScore());

        result.setTeamTwoName(baseTournament.getTeamTwoName());
        result.setTeamTwoScore(baseTournament.getTeamTwoScore());
        //球员
        BaseBasketballPlayer baseBasketballPlayer = iBaseBasketballPlayerService.selectBaseBasketballPlayerById(dto.getPlayerId());
        AssertUtil.notNull(baseBasketballPlayer, "球员没有找到!");
        result.setPlayerAvatar(baseBasketballPlayer.getProfilePicture());
        result.setPlayerName(baseBasketballPlayer.getName());
        result.setPlayerNumber(baseBasketballPlayer.getPlayerNumber());

        //球员球队
        BasketballPlayerAndTeam basketballPlayerAndTeam = basketballPlayerAndTeamMapper.selectPlayerId(dto.getPlayerId(), 0);
        AssertUtil.notNull(basketballPlayerAndTeam,"球队异常!");

        //球队胜负数据
        List<BaseTeamGrouping> baseTeamGroupings = iBaseTeamGroupingService.teamRankingList(baseTournament.getContestId());
        if (CollUtil.isNotEmpty(baseTeamGroupings)) {
            for (BaseTeamGrouping item : baseTeamGroupings) {
                List<BaseTeanGroupingPlayTeam> teanGroupingPlayTeamList = item.getTeanGroupingPlayTeamList();
                if (CollUtil.isNotEmpty(teanGroupingPlayTeamList)) {
                    int num = 1;
                    for (BaseTeanGroupingPlayTeam team : teanGroupingPlayTeamList) {
                        if (Objects.equals(team.getBasketballTeamId(), basketballPlayerAndTeam.getTeamId())) {
                            result.setTeamRank(item.getName() + " 排名NO." + num);
                            result.setWinNum(team.getWinNum());
                            result.setLoseNum(team.getLossNum());
                        }
                        num++;
                    }
                }
            }
        }

        List<BasePlayerLog> basePlayerLogs = basePlayerLogMapper.selectByTournamentIdAndPlayerIdAndSubsection(dto.getTournamentId(), dto.getPlayerId(), null);
        result.getScoreListList().add(buildScoreList(basePlayerLogs, 1L));
        result.getScoreListList().add(buildScoreList(basePlayerLogs, 2L));
        result.getScoreListList().add(buildScoreList(basePlayerLogs, 3L));
        result.getScoreListList().add(buildScoreList(basePlayerLogs, 4L));
        //全场总计
        PersonalDataResultDto.ScoreList scoreList = buildScoreList(basePlayerLogs, 0L);
        result.getScoreListList().add(scoreList);
        result.setGbpm(scoreList.getGbpm());

        result.setScoreMovementVO(basePlayerLogService.scoreMovement(dto.getTournamentId()));
        return result;
    }

    /**
     * 计算分节数据
     *
     * @param subsectionList
     * @param subsection
     * @return
     */
    private PersonalDataResultDto.ScoreList buildScoreList(List<BasePlayerLog> subsectionList, long subsection) {
        PersonalDataResultDto.ScoreList scoreList = new PersonalDataResultDto.ScoreList();
        if (!Objects.equals(subsection, 0L)) {
            if (Objects.equals(subsection, 4L)) {
                subsectionList = subsectionList.stream().filter(bo -> bo.getSubsection() >= subsection).collect(Collectors.toList());
            } else {
                subsectionList = subsectionList.stream().filter(bo -> Objects.equals(bo.getSubsection(), subsection)).collect(Collectors.toList());
            }
        }

        scoreList.setSubsection(subsection);
        scoreList.setScore(subsectionList.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum));
        scoreList.setBackboard(subsectionList.stream().filter(bo -> Objects.equals(bo.getType(), PlayerLogType.BACKBOARD.getCode())).count());
        scoreList.setAssist(subsectionList.stream().filter(bo -> Objects.equals(bo.getType(), PlayerLogType.ASSIST.getCode())).count());
        scoreList.setSteal(subsectionList.stream().filter(bo -> Objects.equals(bo.getType(), PlayerLogType.STRAL.getCode())).count());
        scoreList.setBlock(subsectionList.stream().filter(bo -> Objects.equals(bo.getType(), PlayerLogType.BLOCK_SHOT.getCode())).count());
        scoreList.setFoul(subsectionList.stream().filter(bo -> Objects.equals(bo.getType(), PlayerLogType.FOUL.getCode())).count());
        scoreList.setMistake(subsectionList.stream().filter(bo -> Objects.equals(bo.getType(), PlayerLogType.MISTAKE.getCode())).count());

        long threePointHit = CommonStreamUtil.filter(subsectionList, o -> Objects.equals(o.getType(), PlayerLogType.THREE_POINT_HIT.getCode())).size();
        long threeNotPointHit = CommonStreamUtil.filter(subsectionList, o -> Objects.equals(o.getType(), PlayerLogType.THREE_NOT_POINT_HIT.getCode())).size();
        long twoPointHit = CommonStreamUtil.filter(subsectionList, o -> Objects.equals(o.getType(), PlayerLogType.TWO_POINT_HIT.getCode())).size();
        long twoNotPointHit = CommonStreamUtil.filter(subsectionList, o -> Objects.equals(o.getType(), PlayerLogType.TWO_NOT_POINT_HIT.getCode())).size();
        long pointHit = CommonStreamUtil.filter(subsectionList, o -> Objects.equals(o.getType(), PlayerLogType.POINT_HIT.getCode())).size();
        long notPointHit = CommonStreamUtil.filter(subsectionList, o -> Objects.equals(o.getType(), PlayerLogType.NOT_POINT_HIT.getCode())).size();
        long shootPointNum = threePointHit + twoPointHit + pointHit;
        long shootTotalNum = shootPointNum + threeNotPointHit + twoNotPointHit + notPointHit;
        scoreList.setBasket(shootPointNum + "/" + shootTotalNum);

        if (twoPointHit > 0) {
            scoreList.setTwoPointRate(BigDecimal.valueOf(twoPointHit).divide(BigDecimal.valueOf(twoPointHit + twoNotPointHit), 2, RoundingMode.HALF_UP));
        }
        if (threePointHit > 0) {
            scoreList.setThreePointRate(BigDecimal.valueOf(threePointHit).divide(BigDecimal.valueOf(threePointHit + threeNotPointHit), 2, RoundingMode.HALF_UP));
        }
        if (pointHit > 0) {
            scoreList.setPointRate(BigDecimal.valueOf(pointHit).divide(BigDecimal.valueOf(pointHit + notPointHit), 2, RoundingMode.HALF_UP));
        }
        //真实命中率
        //总分 / (2* (二分出手+三分出手+ (0.44*罚球出手) ))
        double v = 0.44 * (pointHit + notPointHit);
        double v1 = 2 * ((twoPointHit + twoNotPointHit) + (threePointHit + threeNotPointHit) + v);
        BigDecimal divide1 = BigDecimal.ZERO;
        if (scoreList.getScore() > 0 && v1 > 0) {
            divide1 = BigDecimal.valueOf(scoreList.getScore()).divide(BigDecimal.valueOf(v1), 2, RoundingMode.HALF_UP);
        }
        scoreList.setRate(divide1);
        if (Objects.equals(subsection, 0L)) {
            //投篮出手
            double v2 = (threePointHit + threeNotPointHit + twoNotPointHit + twoPointHit) * 0.55;
            //罚球出手
            double v3 = (pointHit + notPointHit) * 0.25;
            //命中得分
            double v4 = (threePointHit * 2.43) + (twoPointHit * 1.39) + (pointHit * 0.79);
            //篮板+助攻
            double v5 = (scoreList.getBackboard() * 0.22) + (scoreList.getAssist() * 0.43);
            //抢断+盖帽
            double v6 = (scoreList.getSteal() * 1.34) + (scoreList.getBlock() * 0.64);
            //失误+犯规
            double v7 = (scoreList.getMistake() * 0.95) + (scoreList.getFoul() * 0.34);

            double v8 = (v4 + v5 + v6) - (v2 + v3 + v7);
            BigDecimal bigDecimal = BigDecimal.valueOf(v8);
            scoreList.setGbpm(bigDecimal.setScale(2, RoundingMode.HALF_UP));
        }
        return scoreList;
    }

    public String ImageToPdf(MultipartFile file, String fileName) throws Exception {
        // 构建 PDF 文件名
        String pdfFileName = fileName.substring(0, fileName.lastIndexOf(".")) + System.currentTimeMillis() + ".pdf";

        // 创建 PDF 文档对象
        Document doc = new Document(PageSize.A4, 20, 20, 20, 20); // 设置页边距
        PdfWriter.getInstance(doc, new FileOutputStream(pdfFileName));

        // 打开文档
        doc.open();

        // 从 MultipartFile 中获取图片
        Image image = Image.getInstance(file.getBytes());

        // 获取 A4 页面的实际可用宽度（减去边距）
        float pageWidth = PageSize.A4.getWidth() - 40; // 两边各 20pt 边距
        float pageHeight = PageSize.A4.getHeight() - 40; // 上下各 20pt 边距

        // 计算图片的缩放比例
        float scale = Math.min(pageWidth / image.getWidth(), pageHeight / image.getHeight());

        // 调整图片大小
        image.scalePercent(scale * 100);

        // 设置图片居中
        image.setAlignment(Image.ALIGN_CENTER | Image.ALIGN_MIDDLE);

        // 添加图片到文档
        doc.add(image);

        // 关闭文档
        doc.close();

        // 打印 PDF 文件名
        System.out.println(pdfFileName);

        // 创建文件对象
        File pdfFile = new File(pdfFileName);

        // 下载 PDF 文件（假设你已经有了这个方法）
        downloadDataPfd(pdfFileName, pdfFile);

        // 返回 PDF 文件名
        return pdfFileName;
    }

    /**
     * @param height 图片的高度
     * @param weight 图片的宽度
     * @return 压缩百分比
     * @Description: 等比压缩，获取压缩百分比
     */
    private static int getPercent(float height, float weight) {
        float percent = 0.0F;
        if (height > weight) {
            percent = PageSize.A4.getHeight() / height * 100;
        } else {
            percent = PageSize.A4.getWidth() / weight * 100;
        }
        return Math.round(percent);
    }


    private String downloadDataPfd(String objectName, File file) {
        try {
            // 创建OSSClient对象
            OSS ossClient = new OSSClientBuilder().build(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);

            // 上传文件到OSS
            FileInputStream inputStream = new FileInputStream(file);
            PutObjectResult putObjectResult = ossClient.putObject(new PutObjectRequest(bucketName, objectName, inputStream));
            // 关闭OSSClient
            ossClient.shutdown();
            return objectName;
        } catch (Exception e) {
            e.printStackTrace();
            return "文件上传失败：【{}】" + e.getMessage();
        }
    }

    private List<BasePdfDataPlayListVO> buildPdfHomePlayerList(List<BasePlayerLog> homePlayerLogList, Long teamId) {
        homePlayerLogList = CommonStreamUtil.filter(homePlayerLogList, o -> Objects.nonNull(o.getBasketballPlayerId()));
        Map<Long, List<BasePlayerLog>> playerMap = CommonStreamUtil.group(homePlayerLogList, BasePlayerLog::getBasketballPlayerId);
        List<BasePdfDataPlayListVO> pdfHomePlayerList = new ArrayList<>();
        List<BasketballPlayerAndTeam> basketballPlayerAndTeams = basketballPlayerAndTeamMapper.selectByTeamThenPlay(teamId);
        if (CollUtil.isNotEmpty(basketballPlayerAndTeams)) {
            //获取球员
            Set<Long> playerIds = CommonStreamUtil.transSet(basketballPlayerAndTeams, BasketballPlayerAndTeam::getPlayerId);
            List<BaseBasketballPlayer> baseBasketballPlayers = iBaseBasketballPlayerService.listByIds(playerIds);
            if (CollUtil.isNotEmpty(baseBasketballPlayers)) {
                baseBasketballPlayers.forEach(item -> {
                    BasePdfDataPlayListVO pdfData = new BasePdfDataPlayListVO();
                    pdfData.setPlayerNumber(item.getPlayerNumber());
                    pdfData.setPlayerName(item.getName());
                    if (playerMap.containsKey(item.getId())) {
                        List<BasePlayerLog> basePlayerLogList1 = playerMap.get(item.getId());
                        long twoPointHit = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.TWO_POINT_HIT.getCode())).size();
                        long twoNotPointHit = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.TWO_NOT_POINT_HIT.getCode())).size();
                        pdfData.setAllTwoPoint(twoPointHit + twoNotPointHit);
                        pdfData.setTwoPoint(twoPointHit);
                        pdfData.setTwoPointScore(twoPointHit * 2);
                        BigDecimal twoRate = BigDecimal.ZERO;
                        if (twoPointHit > 0) {
                            twoRate = BigDecimal.valueOf(twoPointHit).divide(BigDecimal.valueOf(pdfData.getAllTwoPoint()), 2, RoundingMode.HALF_UP);
                        }
                        pdfData.setTwoPointRate(twoRate);

                        long threePointHit = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.THREE_POINT_HIT.getCode())).size();
                        long threeNotPointHit = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.THREE_NOT_POINT_HIT.getCode())).size();
                        pdfData.setAllThreePoint(threePointHit + threeNotPointHit);
                        pdfData.setThreePoint(threePointHit);
                        pdfData.setThreePointScore(threePointHit * 3);
                        BigDecimal threeRate = BigDecimal.ZERO;
                        if (threePointHit > 0) {
                            threeRate = BigDecimal.valueOf(threePointHit).divide(BigDecimal.valueOf(pdfData.getAllThreePoint()), 2, RoundingMode.HALF_UP);
                        }
                        pdfData.setThreePointRate(threeRate);

                        long pointHit = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.POINT_HIT.getCode())).size();
                        long notPointHit = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.NOT_POINT_HIT.getCode())).size();
                        pdfData.setAllPoint(pointHit + notPointHit);
                        pdfData.setPoint(pointHit);
                        pdfData.setPointScore(pointHit);
                        BigDecimal rate = BigDecimal.ZERO;
                        if (pointHit > 0) {
                            rate = BigDecimal.valueOf(pointHit).divide(BigDecimal.valueOf(pdfData.getAllPoint()), 2, RoundingMode.HALF_UP);
                        }
                        pdfData.setPointRate(rate);

                        long assist = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.ASSIST.getCode())).size();
                        long backboard = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.BACKBOARD.getCode())).size();
                        long stral = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.STRAL.getCode())).size();
                        long mistake = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.MISTAKE.getCode())).size();
                        long foul = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.FOUL.getCode())).size();
                        long blockShot = CommonStreamUtil.filter(basePlayerLogList1, o -> Objects.equals(o.getType(), PlayerLogType.BLOCK_SHOT.getCode())).size();
                        Long reduce = basePlayerLogList1.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum);
                        pdfData.setScore(reduce);
                        pdfData.setAssist(assist);
                        pdfData.setBackboard(backboard);
                        pdfData.setStral(stral);
                        pdfData.setMistake(mistake);
                        pdfData.setFoul(foul);
                        pdfData.setBlockShot(blockShot);
                        long per = (reduce + backboard + assist + stral + blockShot) - (twoNotPointHit + threeNotPointHit + notPointHit + mistake);
                        pdfData.setPer(per);

                        //真实命中率
                        //总分 / (2* (二分出手+三分出手+ (0.44*罚球出手) ))
                        double v = 0.44 * (pointHit + notPointHit);
                        double v1 = 2 * (pdfData.getAllThreePoint() + pdfData.getAllTwoPoint() + v);
                        BigDecimal divide1 = BigDecimal.ZERO;
                        if (reduce > 0 && v1 > 0) {
                            divide1 = BigDecimal.valueOf(reduce).divide(BigDecimal.valueOf(v1), 2, RoundingMode.HALF_UP);
                        }
                        pdfData.setRate(divide1);
                    }
                    pdfHomePlayerList.add(pdfData);
                });
            }
        }
        return pdfHomePlayerList;
    }

    private void setCoach(BaseTournamentResponseVO baseTournamentResponseVO) {
        if (Objects.nonNull(baseTournamentResponseVO.getOneTeam())) {
            List<BaseCoach> baseCoachList = iBaseCoachService.selectBaseCoachList(BaseCoach.builder()
                    .playerId(baseTournamentResponseVO.getOneTeam().getId()).build());
            baseTournamentResponseVO.getOneTeam().setBaseCoachList(baseCoachList);
        }
        if (Objects.nonNull(baseTournamentResponseVO.getTwoTeam())) {
            List<BaseCoach> baseCoachList = iBaseCoachService.selectBaseCoachList(BaseCoach.builder()
                    .playerId(baseTournamentResponseVO.getTwoTeam().getId()).build());
            baseTournamentResponseVO.getTwoTeam().setBaseCoachList(baseCoachList);
        }
    }

    private void setPlayer(BaseTournamentResponseVO baseTournamentResponseVO) {
        if (Objects.nonNull(baseTournamentResponseVO.getOneTeam())) {
            List<BaseBasketballPlayer> baseBasketballPlayers = iBaseBasketballPlayerService.selectBaseBasketballPlayerList(BaseBasketballPlayer.builder()
                    .playerId(baseTournamentResponseVO.getOneTeam().getId()).build());
            baseBasketballPlayers.forEach(vo -> vo.setPlayerNumberInt(Integer.parseInt(vo.getPlayerNumber())));
            baseBasketballPlayers = baseBasketballPlayers.stream()
                    .sorted(Comparator.comparing(BaseBasketballPlayer::getIsUp).reversed()
                            .thenComparing(BaseBasketballPlayer::getPlayerNumberInt)).collect(Collectors.toList());
            baseTournamentResponseVO.getOneTeam().setBaseBasketballPlayersList(baseBasketballPlayers);
        }
        if (Objects.nonNull(baseTournamentResponseVO.getTwoTeam())) {
            List<BaseBasketballPlayer> baseBasketballPlayers = iBaseBasketballPlayerService.selectBaseBasketballPlayerList(BaseBasketballPlayer.builder()
                    .playerId(baseTournamentResponseVO.getTwoTeam().getId()).build());
            baseBasketballPlayers.forEach(vo -> vo.setPlayerNumberInt(Integer.parseInt(vo.getPlayerNumber())));
            baseBasketballPlayers = baseBasketballPlayers.stream()
                    .sorted(Comparator.comparing(BaseBasketballPlayer::getIsUp).reversed()
                            .thenComparing(BaseBasketballPlayer::getPlayerNumberInt)).collect(Collectors.toList());

            baseTournamentResponseVO.getTwoTeam().setBaseBasketballPlayersList(baseBasketballPlayers);
        }
    }

    private void setTournamentPersonnel(BaseTournamentResponseVO baseTournamentResponseVO, Long id) {
        List<BaseTournamentPersonnel> list = iBaseTournamentPersonnelService.selectBaseTournamentPersonnelList(
                BaseTournamentPersonnel.builder().tournamentId(id).level(1L).build());
        baseTournamentResponseVO.setTournamentPersonnelList(list);
    }

    /**
     * 查询赛事列表
     *
     * @param baseTournament 赛事
     * @return 赛事
     */
    @Override
    public TableDataInfo selectBaseTournamentList(BaseTournament baseTournament) {
        if (StringUtils.isNotEmpty(baseTournament.getSeasonName())) {
            List<BaseBasketballTeam> teamList = baseBasketballTeamMapper.selectByName(baseTournament.getSeasonName(), baseTournament.getContestId());
            if (CollUtil.isEmpty(teamList)) {
                return new TableDataInfo(new ArrayList<>(), 0);
            }
            List<Long> teamIds = CommonStreamUtil.transList(teamList, BaseBasketballTeam::getId);
            baseTournament.setSeasonTeamId(teamIds);
        }
        startPage();
        List<BaseTournament> baseTournaments = baseTournamentMapper.selectBaseTournamentList(baseTournament);
        if (CollUtil.isEmpty(baseTournaments)) {
            return new TableDataInfo(new ArrayList<>(), 0);
        }
        List<Long> tournamentIds = baseTournaments.stream().map(BaseTournament::getId).collect(Collectors.toList());
        List<BasePlayerLog> playerLogList = basePlayerLogMapper.selectList(Wrappers.<BasePlayerLog>lambdaQuery()
                .in(BasePlayerLog::getTournamentId, tournamentIds)
                .eq(BasePlayerLog::getIsDeleted, 0)
        );
        Map<Long, List<BasePlayerLog>> playList = playerLogList.stream().collect(Collectors.groupingBy(BasePlayerLog::getTournamentId));

        List<BaseTournamentResponseVO> responseVOList = new ArrayList<>();
        //根据比赛队伍id 拿到队伍详情信息
        baseTournaments.forEach(item -> {

            if (playList.containsKey(item.getId())) {
                List<BasePlayerLog> playerLogList2 = playList.get(item.getId());
                Map<Long, List<BasePlayerLog>> collect = playerLogList2.stream().collect(Collectors.groupingBy(BasePlayerLog::getBasketballTeamId));
                if (collect.containsKey(item.getTeamOneId())) {
                    List<BasePlayerLog> playerLogList1 = collect.get(item.getTeamOneId());
                    Long reduce = playerLogList1.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum);
                    item.setTeamOneScore(reduce);
                }
                if (collect.containsKey(item.getTeamTwoId())) {
                    List<BasePlayerLog> playerLogList1 = collect.get(item.getTeamTwoId());
                    Long reduce = playerLogList1.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum);
                    item.setTeamTwoScore(reduce);
                }
            }
            BaseTournamentResponseVO baseTournamentResponseVO = BeanUtil.copyProperties(item, BaseTournamentResponseVO.class);
            //拿到队伍信息
            setTeam(baseTournamentResponseVO, item.getTeamOneId(), PREFIX.concat(String.valueOf(item.getTeamOneId())), 1);
            setTeam(baseTournamentResponseVO, item.getTeamTwoId(), PREFIX.concat(String.valueOf(item.getTeamTwoId())), 2);

            String fiveUrl = "http://daping.yundongshugenmatch.cn/#/MatchSchedule5V5?matchId=" + baseTournamentResponseVO.getId() + "&contestId=" + item.getContestId();
            String threeUrl = "http://daping.yundongshugenmatch.cn/#/MatchSchedule3V3?matchId=" + baseTournamentResponseVO.getId() + "&contestId=" + item.getContestId();
            baseTournamentResponseVO.setFiveUrl(fiveUrl);
            baseTournamentResponseVO.setThreeUrl(threeUrl);

            responseVOList.add(baseTournamentResponseVO);

        });
        return new TableDataInfo(responseVOList, (int) new PageInfo(baseTournaments).getTotal());
    }


    /**
     * 查询赛事列表
     *
     * @param
     * @return 赛事
     */
    @Override
    public TableDataInfo selectBaseTournamentList(Long contestId, int state, Long teamId, Integer pageNum, Integer pageSize) {

        List<BaseTournament> baseTournaments = baseTournamentMapper.selectBaseTournamentListTeam(contestId, state, teamId);
        int size = baseTournaments.size();
        if (CollUtil.isEmpty(baseTournaments)) {
            return new TableDataInfo(new ArrayList<>(), 0);
        }
        if (Objects.nonNull(pageNum) && Objects.nonNull(pageSize)) {
            baseTournaments = baseTournaments.stream()
                    .skip((long) (pageNum - 1) * pageSize)
                    .limit(pageSize).collect(Collectors.toList());
            if (CollUtil.isEmpty(baseTournaments)) {
                return new TableDataInfo(new ArrayList<>(), 0);
            }
        }
        List<Long> tournamentIds = baseTournaments.stream().map(BaseTournament::getId).collect(Collectors.toList());
        List<BasePlayerLog> playerLogList = basePlayerLogMapper.selectList(Wrappers.<BasePlayerLog>lambdaQuery()
                .in(BasePlayerLog::getTournamentId, tournamentIds)
                .eq(BasePlayerLog::getIsDeleted, 0)
        );
        Map<Long, List<BasePlayerLog>> playList = playerLogList.stream().collect(Collectors.groupingBy(BasePlayerLog::getTournamentId));
        List<BaseTournamentResponseVO> responseVOList = new ArrayList<>();
        //根据比赛队伍id 拿到队伍详情信息
        baseTournaments.forEach(item -> {
            if (playList.containsKey(item.getId())) {
                List<BasePlayerLog> playerLogList2 = playList.get(item.getId());
                Map<Long, List<BasePlayerLog>> collect = playerLogList2.stream().collect(Collectors.groupingBy(BasePlayerLog::getBasketballTeamId));
                if (collect.containsKey(item.getTeamOneId())) {
                    List<BasePlayerLog> playerLogList1 = collect.get(item.getTeamOneId());
                    Long reduce = playerLogList1.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum);
                    item.setTeamOneScore(reduce);
                }
                if (collect.containsKey(item.getTeamTwoId())) {
                    List<BasePlayerLog> playerLogList1 = collect.get(item.getTeamTwoId());
                    Long reduce = playerLogList1.stream().map(BasePlayerLog::getScore).reduce(0L, Long::sum);
                    item.setTeamTwoScore(reduce);
                }
            }
            BaseTournamentResponseVO baseTournamentResponseVO = BeanUtil.copyProperties(item, BaseTournamentResponseVO.class);
            //拿到队伍信息
            setTeam(baseTournamentResponseVO, item.getTeamOneId(), PREFIX.concat(String.valueOf(item.getTeamOneId())), 1);
            setTeam(baseTournamentResponseVO, item.getTeamTwoId(), PREFIX.concat(String.valueOf(item.getTeamTwoId())), 2);
            responseVOList.add(baseTournamentResponseVO);

        });

        return new TableDataInfo(responseVOList, size);
    }

    /**
     * 拿到队伍信息
     */
    private void setTeam(BaseTournamentResponseVO baseTournamentResponseVO, Long teamOneId, String teamId, int temp) {
        if (redisService.hasKey(teamId)) {
            //存储第一个队伍
            if (temp == 1) {
                baseTournamentResponseVO.setOneTeam(redisService.getCacheObject(teamId));
            } else {
                baseTournamentResponseVO.setTwoTeam(redisService.getCacheObject(teamId));
            }
        } else {
            //缓存拿不到 数据库拿
            BaseBasketballTeam baseBasketballTeam = baseBasketballTeamMapper.selectBaseBasketballTeamById(teamOneId);
            if (ObjectUtil.isNotNull(baseBasketballTeam)) {
                if (temp == 1) {
                    baseTournamentResponseVO.setOneTeam(baseBasketballTeam);
                } else {
                    baseTournamentResponseVO.setTwoTeam(baseBasketballTeam);
                }
                //放缓存中
                redisService.setCacheObject(teamId, baseBasketballTeam);
            }
        }
    }

    /**
     * 新增赛事
     *
     * @param baseTournament 赛事
     * @return 结果
     */
    @Override
    public int insertBaseTournament(BaseTournament baseTournament) {

        baseTournament.setCreateTime(DateUtils.getNowDate());

        loginUserSetUtil.populateFields(baseTournament, 1);
        //判断是否还有可用比赛场次
        buildContestTournamentNum(baseTournament.getContestId());
        return baseTournamentMapper.insertBaseTournament(baseTournament);
    }

    private void buildContestTournamentNum(Long contestId) {
        BaseContest contest = iBaseContestService.getById(contestId);
        if(Objects.isNull(contest)){
            throw new RuntimeException("联赛出错!");
        }
        Long beginStateCount = baseTournamentMapper.selectByCount(contestId);
        Long count = baseTournamentMapper.selectByIsDeletedCount(contestId);
        beginStateCount = beginStateCount + count;
        if (Objects.nonNull(contest.getTournamentNum()) && beginStateCount >= contest.getTournamentNum()){
            throw new RuntimeException("比赛场次不足,请联系管理员!");
        }
    }

    /**
     * 修改赛事
     *
     * @param baseTournament 赛事
     * @return 结果
     */
    @Override
    public int updateBaseTournament(BaseTournament baseTournament) {
        baseTournament.setUpdateTime(DateUtils.getNowDate());
        if (Objects.equals(baseTournament.getState(), 1)) {
            Long cacheUserId = redisService.getCacheLong(CacheConstants.BASE_PLAYER_LOG_CACHE_KEY + baseTournament.getId());
            if (Objects.nonNull(cacheUserId) && !Objects.equals(cacheUserId, SecurityUtils.getUserId())){
                SysUser sysUser = sysUserService.selectUserById(cacheUserId);
                throw new RuntimeException(sysUser.getNickName() + "正在使用,限制上线!");
            }
            BaseContest byId = iBaseContestService.getById(SecurityUtils.getContestId());
            if (Objects.isNull(byId)) {
                throw new RuntimeException("获取当前联赛失败");
            }
            BaseTournament byId1 = this.getById(baseTournament.getId());
            int num = 0;
            if (Objects.equals(byId.getScoringWay(), 0L)) {
                num = 5;
            } else {
                num = 3;
            }
            if (iBaseBasketballPlayerService.getIsUp(byId1.getTeamOneId(), byId1.getTeamTwoId(), num)) {
                throw new RuntimeException("当前首发人数少于" + num + "人数,请修改首发上场人数");
            }
        }
        //恢复比赛
        BaseTournament tournament = baseTournamentMapper.selectById(baseTournament.getId());
        if (Objects.nonNull(tournament) && Objects.equals(tournament.getIsDeleted(), 1L) &&
                Objects.equals(baseTournament.getIsDeleted(), 0L)) {
            //判断是否还有可用比赛场次
            buildContestTournamentNum(tournament.getContestId());
        }
        loginUserSetUtil.populateFields(baseTournament, 2);
        return baseTournamentMapper.updateById(baseTournament);
    }


    /**
     * 删除赛事信息
     *
     * @param id 赛事主键
     * @return 结果
     */
    @Override
    public int deleteBaseTournamentById(Long id) {
        return baseTournamentMapper.deleteBaseTournamentById(id);
    }

    /**
     * 弃权
     *
     * @param id           比赛id
     * @param abstentionId 弃权队伍id
     * @return
     */
    @Override
    public int abstention(Long id, Long abstentionId) {
        //拿到详情数据
        BaseTournament baseTournament = selectBaseTournamentById(id);
        if (ObjectUtil.isNull(baseTournament)) {
            return -1;
        }

        Long isWinId = -1L;

        LambdaUpdateWrapper<BaseTournament> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BaseTournament::getId, id);
        updateWrapper.set(BaseTournament::getIsWin, isWinId);
        updateWrapper.set(BaseTournament::getTournamentEndTime, new Date());
        updateWrapper.set(BaseTournament::getState, 2);
        updateWrapper.set(BaseTournament::getUpdateTime, new Date());
        updateWrapper.set(BaseTournament::getUpdateUserId, baseTournament.getUpdateUserId());
        updateWrapper.set(BaseTournament::getUpdateUserName, baseTournament.getUpdateUserName());

        if (baseTournament.getTeamOneId().equals(abstentionId)) {
            isWinId = baseTournament.getTeamTwoId();
            updateWrapper.set(BaseTournament::getIsWin, isWinId);
            updateWrapper.set(BaseTournament::getTeamTwoScore, 20l);
            updateWrapper.set(BaseTournament::getTeamOneScore, 0l);
        } else {
            isWinId = baseTournament.getTeamOneId();
            updateWrapper.set(BaseTournament::getIsWin, isWinId);
            updateWrapper.set(BaseTournament::getTeamTwoScore, 0l);
            updateWrapper.set(BaseTournament::getTeamOneScore, 20l);
        }
        loginUserSetUtil.populateFields(baseTournament, 2);

        List<BaseTeanGroupingPlayTeam> list = iBaseTeanGroupingPlayTeamService.list(Wrappers.<BaseTeanGroupingPlayTeam>lambdaQuery()
                .in(BaseTeanGroupingPlayTeam::getBasketballTeamId, baseTournament.getTeamOneId(), baseTournament.getTeamTwoId()));
        if (CollUtil.isNotEmpty(list) && list.size() == 2) {
            geTabstentionTeanGroupingSum(list, baseTournament.getTeamOneId(), isWinId, baseTournament.getTeamOneScore() - baseTournament.getTeamTwoScore());
            geTabstentionTeanGroupingSum(list, baseTournament.getTeamTwoId(), isWinId, baseTournament.getTeamTwoScore() - baseTournament.getTeamOneScore());
            iBaseTeanGroupingPlayTeamService.updateBatchById(list);
        }
        return baseMapper.update(null, updateWrapper);
    }

    /**
     * 结束比赛
     *
     * @param id 比赛id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int overTournament(Long id) {
        log.info("结束比赛,{}", id);
        //拿到详情数据
        BaseTournament baseTournament = selectBaseTournamentById(id);
        if (ObjectUtil.isNull(baseTournament) || Objects.equals(baseTournament.getState(), 2)) {
            return -1;
        }
        BasePlayerLog basePlayerLog1 = basePlayerLogMapper.selectOne(Wrappers.<BasePlayerLog>lambdaQuery()
                .eq(BasePlayerLog::getTournamentId, id)
                .orderByDesc(BasePlayerLog::getSubsection)
                .last("limit 1"));
        if (Objects.nonNull(basePlayerLog1)) {
            baseTournament.setSubsection(basePlayerLog1.getSubsection() > baseTournament.getSubsection() ? basePlayerLog1.getSubsection() : baseTournament.getSubsection());
        }
        //获取每个队伍总分值
        Long oneScore = basePlayerLogMapper.getScore(baseTournament.getTeamOneId(), id);
        Long twoScore = basePlayerLogMapper.getScore(baseTournament.getTeamTwoId(), id);

        //比赛结束记录
        BasePlayerLog basePlayerLog = new BasePlayerLog();

        basePlayerLog.setTournamentId(id).setType(PlayerLogType.OVER.getCode())
                .setBasketballPlayerId(-1L).setBasketballTeamId(-1L)
                .setContestId(baseTournament.getContestId())
                .setScore(0L)
                .setSubsection(baseTournament.getSubsection());

        loginUserSetUtil.populateFields(basePlayerLog, 1);
        basePlayerLogMapper.insert(basePlayerLog);

        loginUserSetUtil.populateFields(baseTournament, 2);

        Long aLongTeam = oneScore > twoScore ? baseTournament.getTeamOneId() : baseTournament.getTeamTwoId();

        //更新当前比赛信息
        LambdaUpdateWrapper<BaseTournament> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(BaseTournament::getId, id);
        updateWrapper.set(BaseTournament::getState, 2);
        updateWrapper.set(BaseTournament::getUpdateTime, new Date());
        updateWrapper.set(BaseTournament::getTournamentEndTime, new Date());
        updateWrapper.set(BaseTournament::getTeamOneScore, oneScore);
        updateWrapper.set(BaseTournament::getTeamTwoScore, twoScore);
        updateWrapper.set(BaseTournament::getIsWin, aLongTeam);
        updateWrapper.set(BaseTournament::getSubsection, baseTournament.getSubsection());
        updateWrapper.set(BaseTournament::getUpdateUserId, baseTournament.getUpdateUserId());
        updateWrapper.set(BaseTournament::getUpdateUserName, baseTournament.getUpdateUserName());


        List<BaseTeanGroupingPlayTeam> list = iBaseTeanGroupingPlayTeamService.list(Wrappers.<BaseTeanGroupingPlayTeam>lambdaQuery()
                .in(BaseTeanGroupingPlayTeam::getBasketballTeamId, baseTournament.getTeamOneId(), baseTournament.getTeamTwoId()));
        if (CollUtil.isNotEmpty(list) && list.size() == 2) {
            getTeanGroupingSum(list, baseTournament.getTeamOneId(), aLongTeam, oneScore - twoScore);
            getTeanGroupingSum(list, baseTournament.getTeamTwoId(), aLongTeam, twoScore - oneScore);
            iBaseTeanGroupingPlayTeamService.updateBatchById(list);
        }
        int update = baseMapper.update(null, updateWrapper);
        if (update > 0) {
            redisService.deleteObject(CacheConstants.BASE_PLAYER_LOG_ID + id);

        }
        //修正视频锦集
        iBaseLivePlayBackEvenService.batchRemote(id);
        return update;
    }

    private void geTabstentionTeanGroupingSum(List<BaseTeanGroupingPlayTeam> list, Long teamId, Long aLongTeam, Long score) {
        list.forEach(vo -> {

            if (Objects.equals(vo.getBasketballTeamId(), teamId)) {
                if (Objects.equals(aLongTeam, teamId)) {
                    vo.setWinNum(vo.getWinNum() + 1);
                    vo.setPoints(vo.getPoints() + 2);
                } else {
                    vo.setLossNum(vo.getLossNum() + 1);
                    vo.setAbstentionNum(vo.getAbstentionNum() + 1);
                }
                loginUserSetUtil.populateFields(vo, 2);
            }
        });
    }

    private void getTeanGroupingSum(List<BaseTeanGroupingPlayTeam> list, Long teamId, Long aLongTeam, Long score) {
        list.forEach(vo -> {

            if (Objects.equals(vo.getBasketballTeamId(), teamId)) {
                if (Objects.equals(aLongTeam, teamId)) {
                    vo.setWinNum(vo.getWinNum() + 1);
                    vo.setPoints(vo.getPoints() + 2);
                } else {
                    vo.setLossNum(vo.getLossNum() + 1);
                    vo.setPoints(vo.getPoints() + 1);
                }
                vo.setGoalDifference(vo.getGoalDifference().add(BigDecimal.valueOf(score)));
                loginUserSetUtil.populateFields(vo, 2);
            }
        });
    }

    /**
     * 切换比赛小节
     *
     * @param id
     * @param subsection
     * @return
     */
    @Override
    public int switchGameSections(Long id, Long subsection) {
        //拿到详情数据
        BaseTournament baseTournament = getById(id);
        if (ObjectUtil.isNull(baseTournament)) {
            return -1;
        }
        //校验是否跨越小节
        //更新比赛信息
        BaseTournament tournament = new BaseTournament();
        tournament.setId(id);
        tournament.setSubsection(subsection);
        //填充更新字段
        loginUserSetUtil.populateFields(tournament, 2);
        int i = baseTournamentMapper.updateById(tournament);

//        basePlayerLogService.updateLiveWatermark(id);
        return i;
    }

    /**
     * 批量删除赛事
     *
     * @param ids 需要删除的赛事主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBaseTournamentByIds(Long[] ids) {
        if (ids.length != 1) {
            throw new RuntimeException("不可批量删除");
        }

        List<BaseTournament> baseTournaments = this.listByIds(Arrays.asList(ids));
        List<BaseTournament> collect = baseTournaments.stream().filter(vo -> Objects.equals(vo.getState(), 2)).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(collect)) {
            collect.forEach(baseTournament -> {
                List<BaseTeanGroupingPlayTeam> list = iBaseTeanGroupingPlayTeamService.list(Wrappers.<BaseTeanGroupingPlayTeam>lambdaQuery()
                        .in(BaseTeanGroupingPlayTeam::getBasketballTeamId, baseTournament.getTeamOneId(), baseTournament.getTeamTwoId()));
                if (CollUtil.isNotEmpty(list) && list.size() == 2) {
                    getTeanGroupingSub(list, baseTournament.getTeamOneId(), baseTournament.getIsWin(), baseTournament.getTeamOneScore() - baseTournament.getTeamTwoScore());
                    getTeanGroupingSub(list, baseTournament.getTeamTwoId(), baseTournament.getIsWin(), baseTournament.getTeamTwoScore() - baseTournament.getTeamOneScore());
                    iBaseTeanGroupingPlayTeamService.updateBatchById(list);
                }
            });
        }

        //删除 已有的比分记录
        basePlayerLogMapper.deleteByTournament(ids);

        BaseTournament baseTournament = new BaseTournament();
        baseTournament.setIsDeleted(1L);
        return this.update(baseTournament,
                Wrappers.<BaseTournament>lambdaQuery().in(BaseTournament::getId, ids));
    }

    private void getTeanGroupingSub(List<BaseTeanGroupingPlayTeam> list, Long teamId, Long aLongTeam, Long score) {
        list.forEach(vo -> {

            if (Objects.equals(vo.getBasketballTeamId(), teamId)) {
                if (Objects.equals(aLongTeam, teamId)) {
                    vo.setWinNum(vo.getWinNum() - 1);
                    vo.setPoints(vo.getPoints() - 2);
                } else {
                    vo.setLossNum(vo.getLossNum() - 1);
                    vo.setPoints(vo.getPoints() - 1);
                }
                vo.setGoalDifference(vo.getGoalDifference().subtract(BigDecimal.valueOf(score)));
                loginUserSetUtil.populateFields(vo, 2);
            }
        });
    }

}
